package com.xqb.modules.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xqb.common.constant.Constants;
import com.xqb.common.utils.DateUtils;
import com.xqb.common.utils.SecurityUtils;
import com.xqb.modules.domain.po.ExaExamResults;
import com.xqb.modules.domain.po.ExaQuestion;
import com.xqb.modules.domain.po.ExaQuestionDetail;
import com.xqb.modules.domain.po.ExaUserAnswers;
import com.xqb.modules.mapper.ExaExamResultsMapper;
import com.xqb.modules.mapper.ExaQuestionDetailMapper;
import com.xqb.modules.mapper.ExaQuestionMapper;
import com.xqb.modules.mapper.ExaUserAnswersMapper;
import com.xqb.modules.service.IExaUserAnswersService;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Time;
import java.util.Date;
import java.util.List;

/**
 * 用户答题Service业务层处理
 *
 * @author ruoyi
 * @date 2024-10-17
 */
@Service
public class ExaUserAnswersServiceImpl implements IExaUserAnswersService {
    @Autowired
    private ExaUserAnswersMapper exaUserAnswersMapper;
    @Autowired
    private ExaQuestionMapper exaQuestionMapper;
    @Autowired
    private ExaQuestionDetailMapper exaQuestionDetailMapper;
    @Autowired
    private ExaExamResultsMapper exaExamResultsMapper;

    /**
     * 查询用户答题
     *
     * @param id 用户答题主键
     * @return 用户答题
     */
    @Override
    public ExaUserAnswers selectExaUserAnswersById(Long id) {
        return exaUserAnswersMapper.selectExaUserAnswersById(id);
    }

    /**
     * 查询用户答题列表
     *
     * @param exaUserAnswers 用户答题
     * @return 用户答题
     */
    @Override
    public List<ExaUserAnswers> selectExaUserAnswersList(ExaUserAnswers exaUserAnswers) {
        return exaUserAnswersMapper.selectExaUserAnswersList(exaUserAnswers);
    }

    /**
     * 新增用户答题
     *
     * @param exaUserAnswers 用户答题
     * @return 结果
     */
    @Override
    public int insertExaUserAnswers(ExaUserAnswers exaUserAnswers) {
        exaUserAnswers.setCreateTime(DateUtils.getNowDate());
        return exaUserAnswersMapper.insertExaUserAnswers(exaUserAnswers);
    }

    /**
     * 修改用户答题
     *
     * @param exaUserAnswers 用户答题
     * @return 结果
     */
    @Override
    public int updateExaUserAnswers(ExaUserAnswers exaUserAnswers) {
        exaUserAnswers.setUpdateTime(DateUtils.getNowDate());
        return exaUserAnswersMapper.updateExaUserAnswers(exaUserAnswers);
    }

    /**
     * 批量删除用户答题
     *
     * @param ids 需要删除的用户答题主键
     * @return 结果
     */
    @Override
    public int deleteExaUserAnswersByIds(Long[] ids) {
        return exaUserAnswersMapper.deleteExaUserAnswersByIds(ids);
    }

    /**
     * 批量插入用户答题并更新考试结果。
     *
     * @param exaUserAnswersList 用户答题集合
     * @return 插入的记录数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertExaUserAnswersList(List<ExaUserAnswers> exaUserAnswersList) {
        if (exaUserAnswersList == null || exaUserAnswersList.isEmpty()) {
            return 0;
        }

        ExaExamResults exaExamResults = findOrCreateExamResults(exaUserAnswersList.get(0));
        int totalInsertedRows = 0;
        int correctAnswersCount = 0;
        int scoreForCurrentAnswer = 0;

        for (ExaUserAnswers exaUserAnswer : exaUserAnswersList) {
            int rowsAffected = processAnswer(exaUserAnswer, exaExamResults, correctAnswersCount, scoreForCurrentAnswer);
            totalInsertedRows += rowsAffected;
        }

        updateExamResults(exaExamResults, scoreForCurrentAnswer, correctAnswersCount, exaUserAnswersList.size());
        return totalInsertedRows;
    }

    private ExaExamResults findOrCreateExamResults(ExaUserAnswers exaUserAnswer) {
        LambdaQueryWrapper<ExaExamResults> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ExaExamResults::getUserId, exaUserAnswer.getUserId());
        wrapper.eq(ExaExamResults::getBizId, exaUserAnswer.getBizId());
        ExaExamResults exaExamResults = exaExamResultsMapper.selectOne(wrapper);
        if (exaExamResults == null) {
            exaExamResults = createExamResults(exaUserAnswer);
            exaExamResultsMapper.insert(exaExamResults);
        }
        return exaExamResults;
    }

    private ExaExamResults createExamResults(ExaUserAnswers exaUserAnswer) {
        ExaExamResults examResults = new ExaExamResults();
        examResults.setUserId(SecurityUtils.getUserId());
        examResults.setBizId(exaUserAnswer.getBizId());
        examResults.setCreateTime(DateUtils.getNowDate());
        examResults.setIsOver(Constants.EXA_RESULT_NOT_FINISH);
        return examResults;
    }

    private int processAnswer(ExaUserAnswers exaUserAnswer, ExaExamResults exaExamResults, int correctAnswersCount, int scoreForCurrentAnswer) {
        ExaQuestion exaQuestion = exaQuestionMapper.selectExaQuestionById(exaUserAnswer.getQuestionId());
        if (exaQuestion != null && !exaQuestion.getType().equals(Constants.EXA_QUESTION_SHORT_ANSWER)) {
            ExaQuestionDetail exaQuestionDetail = exaQuestionDetailMapper.selectExaQuestionDetailById(exaUserAnswer.getQuestionId());
            if (exaQuestionDetail != null && exaUserAnswer.getAnswer().equals(exaQuestionDetail.getAnswer())) {
                exaUserAnswer.setScore(exaQuestion.getScore());
                scoreForCurrentAnswer += exaQuestion.getScore();
                correctAnswersCount++;
                exaQuestion.setCorrectTimes(exaQuestion.getCorrectTimes() + 1);
            }
            exaQuestion.setAnswerTimes(exaQuestion.getAnswerTimes() + 1);
            exaQuestionMapper.updateById(exaQuestion);
        }
        return exaUserAnswersMapper.insert(exaUserAnswer);
    }

    private void updateExamResults(ExaExamResults exaExamResults, int scoreForCurrentAnswer, int correctAnswersCount, int totalAnswers) {
        exaExamResults.setScore(scoreForCurrentAnswer);
        if (correctAnswersCount == totalAnswers) {
            exaExamResults.setIsOver(Constants.EXA_RESULT_FINISH);
        }
        long spendTimeMillis = DateUtils.getNowDate().getTime() - exaExamResults.getCreateTime().getTime();
        Date spendTimeDate = new Date(spendTimeMillis);
        Time spendTime = getSpendTime(spendTimeDate);
        exaExamResults.setSpendTime(spendTime);
        exaExamResultsMapper.updateById(exaExamResults);
    }

    @NotNull
    private static Time getSpendTime(Date spendTimeDate) {
        return new Time(spendTimeDate.getTime());
    }


    /**
     * 删除用户答题信息
     *
     * @param id 用户答题主键
     * @return 结果
     */
    @Override
    public int deleteExaUserAnswersById(Long id) {
        return exaUserAnswersMapper.deleteExaUserAnswersById(id);
    }

}
